home *** CD-ROM | disk | FTP | other *** search
- /* MiniDriverTest.c */
- /*
- * MiniDriverTest.c
- * Copyright © 1994 Apple Computer Inc. All Rights Reserved.
- */
- /* .___________________________________________________________________________________.
- | This is a very simple test program for the PCI sample driver. It has not been |
- | compiled for, or tested in, 68000 emulation mode. It is also pretty ugly: it was |
- | written quickly, and while I was debugging the driver. It is not a prize example |
- | of production software. |
- .___________________________________________________________________________________.
- */
- #define TEST_DRIVER 1
- #include <NCRDriverPrivate.h>
- #include <Devices.h>
- #include <Fonts.h>
- #include <ToolUtils.h>
- #include <SegLoad.h>
- #include <SCSI.h>
- #include "MacSCSICommand.h"
- #include "LogLibrary.h"
-
- #ifndef FALSE
- #define FALSE 0
- #define TRUE 1
- #endif
- /*
- * Edit this to define the device to test.
- */
- #define kFirstSCSITargetID 2
- #define kMaxSCSITargetID 2
- #define kSCSITrials 1000
- #define kISRTrials 1
- #define kFirstBlock 1000
- #define kLastBlock 100
- /*
- * if kMinBlocks >kMaxBlocks, the transfer length will change with each request.
- */
- #define kMinBlocks 1 /* Must be at least 1 */
- /*
- * Because we use a 6-byte read command, kMaxBlocks may not exceed 128
- */
- #define kMaxBlocks 64 /* Should be >= kMinBlocks */
- #define kTimeout 2000L
- #define kReadBufferSize 2048 /* Big enough for CD-ROMs */
-
- short gDriverRefNum;
- short gSCSITargetID;
- short gSCSITargetLUN = 0;
- short gTrials;
- Boolean gQuitNow;
- LogRecordPtr gLogRecordPtr;
- MenuHandle gAppleMenu;
- MenuHandle gFileMenu;
- EventRecord gEventRecord;
- Boolean gInForeground;
- IOParam gIOParam;
- NCRSCSIParam gNCRSCSIParam;
- Ptr gReadBufferPtr;
- unsigned long gReadBufferSize;
- unsigned long gCurrentBlockLength;
- unsigned long gDeviceSize;
-
- void DoEventLoop(void);
- void DoMouseEvent(void);
- void DoCommand(
- long menuChoice
- );
- #define MENU_Apple 1
- #define MENU_File 256
- #define kAppleAbout 1
- #define kFileQuit 1
-
- /*
- * SCSI commands
- */
- void DoDeviceTest(void);
- void DoISRTest(void);
- OSErr DoOneISRTest(void);
- OSErr DoBusReset(void);
- OSErr DoTestUnitReady(void);
- OSErr DoDeviceInquiry(void);
- OSErr DoReadCapacity(void);
- OSErr DoReadAllBlocks(void);
- OSErr DoReadBlock(
- unsigned long blockNumber,
- unsigned long nBlocks,
- Boolean dumpBlock
- );
- Boolean DoRequestSense( /* TRUE if Unit Attention */
- unsigned short targetID, /* SCSI Bus ID */
- unsigned short targetLUN /* SCSI LUN -- not supported */
- );
- OSErr DoIORundown(void);
- unsigned long SCSIGetCommandLength(
- const unsigned char *cmdBlock
- );
- Boolean ShowRequestSense( /* TRUE if Unit Attention */
- unsigned short targetID, /* SCSI Bus ID */
- unsigned short targetLUN, /* SCSI LUN -- not supported */
- OSErr callStatus, /* DoDriverIO Request Sense */
- const SCSI_Sense_Data *sense,
- unsigned long actualTransferCount
- );
- #define AppendChar(result, theChar) do { \
- StringPtr _dst = (result); \
- _dst[++_dst[0]] = theChar; \
- } while (0)
- void ShowMemory(
- const Ptr memStart,
- unsigned long byteCount
- );
-
- void AppendHexLeadingZeros(
- StringPtr result,
- unsigned long value,
- short fieldWidth
- );
- void AppendSigned(
- StringPtr result,
- signed long value
- );
- void AppendUnsigned(
- StringPtr result,
- unsigned long value
- );
-
- /*
- * NCR Driver commands
- */
- OSErr DoNCRDriverIOWithSense(
- unsigned short driverAction, /* Input, output, or nothing */
- unsigned short targetID, /* SCSI Bus ID */
- unsigned short targetLUN, /* SCSI LUN -- not supported */
- const unsigned char *scsiCommand, /* SCSI Command itself */
- Ptr dataBufferPtr, /* User data buffer or NULL */
- unsigned long transferCount,
- unsigned long *actualTransferCount
- );
- OSErr DoNCRDriverIO(
- unsigned short driverAction, /* Input, output, or nothing */
- unsigned short targetID, /* SCSI Bus ID */
- unsigned short targetLUN, /* SCSI LUN -- not supported */
- const unsigned char *scsiCommand, /* SCSI Command itself */
- Ptr dataBufferPtr, /* User data buffer or NULL */
- unsigned long transferCount,
- unsigned long *actualTransferCount
- );
- /*
- * A handy macro to clear a (small) structure.
- */
- void ClearMemory(
- register Ptr memPtr,
- register Size memSize
- );
- #undef CLEAR
- #define CLEAR(what) ClearMemory((Ptr) &what, sizeof what)
-
- #define ShowString(string) WriteLogEntry(gLogRecordPtr, 'Test', LogStringFormat, (string))
- #define ShowStatusString(status, string) \
- WriteLogEntry(gLogRecordPtr, 'Test', \
- LogFormat2(kLogFormatSigned, kLogFormatString), \
- (status), (string))
- #define ShowHex(value, string) \
- WriteLogEntry( \
- gLogRecordPtr, 'Test', \
- LogFormat2(kLogFormatAddress, kLogFormatString), \
- (unsigned long) (value), \
- (string) \
- )
- #define ShowDecimal(value, string) \
- WriteLogEntry( \
- gLogRecordPtr, 'Test', \
- LogFormat2(kLogFormatSigned, kLogFormatString), \
- (signed long) (value), \
- (string) \
- )
-
- void
- main(void)
- {
- OSErr status;
- short i;
-
- gLogRecordPtr = MakeLogRecord(kPCIDeviceNameCString, 256);
- MaxApplZone();
- InitGraf(&qd.thePort);
- InitFonts();
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs(0);
- for (i = 0; i < 8; i++)
- MoreMasters();
- HNoPurge((Handle) GetCursor(watchCursor));
- SetCursor(*GetCursor(watchCursor));
- gReadBufferSize = kReadBufferSize * kMaxBlocks;
- gReadBufferPtr = NewPtrClear(gReadBufferSize);
- if (gReadBufferPtr == NULL) {
- ShowString("\pNo memory for read buffer");
- ExitToShell();
- }
- gAppleMenu = NewMenu(MENU_Apple, "\p\024");
- AppendMenu(gAppleMenu, "\p(No About;(-");
- AppendResMenu(gAppleMenu, 'DRVR');
- gFileMenu = NewMenu(MENU_File, "\pFile");
- AppendMenu(gFileMenu, "\pQuit/Q");
- InsertMenu(gAppleMenu, 0);
- InsertMenu(gFileMenu, 0);
- DrawMenuBar();
- status = OpenDriver(kDriverNamePString, &gDriverRefNum);
- if (status != noErr) {
- ShowStatusString(status, "\pCan't open driver");
- ExitToShell();
- }
- DoDeviceTest();
- ExitToShell();
- }
-
- void
- DoDeviceTest(void)
- {
- OSErr status;
- unsigned long startBlock;
- unsigned long nBlocks;
-
- status = DoBusReset();
- if (status != noErr)
- ShowStatusString(status, "\pDo Bus Reset failed");
- else {
- for (gTrials = 0;
- gQuitNow == FALSE
- && (kSCSITrials == 0 || gTrials < kSCSITrials);
- gTrials++) {
- ShowDecimal(gTrials, "\pTrial");
- for (gSCSITargetID = kFirstSCSITargetID;
- gQuitNow == FALSE && gSCSITargetID <= kMaxSCSITargetID;
- gSCSITargetID++) {
- DoEventLoop();
- if (gQuitNow == FALSE) {
- ShowDecimal(gSCSITargetID, "\pTarget");
- status = DoTestUnitReady();
- DoEventLoop();
- if (status == noErr)
- status = DoDeviceInquiry();
- DoEventLoop();
- if (status == noErr)
- status = DoReadCapacity();
- DoEventLoop();
- ShowStatusString(status, "\pDoDeviceTest after init");
- if (1 && status == noErr) { /* Turn on for device exercise */
- nBlocks = kMinBlocks;
- for (startBlock = 0;
- startBlock < (gDeviceSize - kMaxBlocks);
- startBlock++) {
- if (nBlocks > kMaxBlocks)
- nBlocks = kMinBlocks;
- DoEventLoop();
- if (DoReadBlock(startBlock, nBlocks, FALSE) != noErr)
- break;
- ++nBlocks;
- if (gQuitNow) {
- ShowString("\pQuit requested");
- break;
- }
- }
- }
- }
- }
- }
- }
- ShowStatusString(status, "\pDoDeviceTest exits");
- }
-
- void
- DoISRTest(void)
- {
- OSErr status;
-
- for (status = noErr, gTrials = 0;
- kISRTrials == 0 || gTrials < kISRTrials;
- gTrials++) {
- DoEventLoop();
- ShowDecimal(gTrials, "\pISR Trial");
- status = DoOneISRTest();
- if (status != noErr) {
- ShowStatusString(status, "\pISR Test failed");
- gQuitNow = TRUE;
- break;
- }
- }
- }
-
- OSErr
- DoOneISRTest(void)
- {
- OSErr status;
- unsigned char dummyBuffer;
- #define NCR (gNCRSCSIParam)
- #define PB (gIOParam)
-
- status = noErr;
- /*
- * Setup the parameter block
- */
- CLEAR(PB);
- CLEAR(NCR);
- PB.ioRefNum = gDriverRefNum;
- NCR.driverAction = kNCRDriverNoDataPhase;
- NCR.targetID = kNCRMemoryTestBusID;
- NCR.watchdogTimeout = kTimeout; /* Presumably a two second timeout */
- PB.ioBuffer = (Ptr) &dummyBuffer;
- PB.ioReqCount = 1;
- PB.ioMisc = (Ptr) &gNCRSCSIParam;
- status = PBReadSync((ParmBlkPtr) &PB);
- return ((status != noErr) ? status : PB.ioResult);
- #undef PB
- #undef NCR
- }
-
- void
- DoEventLoop(void)
- {
- long menuChoice;
- register WindowPtr theWindow;
- GrafPtr savePort;
- Boolean isActivating;
-
- WaitNextEvent(
- everyEvent,
- &gEventRecord,
- 10L,
- NULL
- );
- theWindow = FrontWindow();
- switch (gEventRecord.what) {
- case nullEvent:
- break;
- case keyDown:
- case autoKey:
- if ((gEventRecord.message & charCodeMask) == '.'
- && (gEventRecord.modifiers & cmdKey) != 0) {
- FlushEvents(keyDown | autoKey, 0);
- gQuitNow = TRUE;
- }
- else if ((gEventRecord.modifiers & cmdKey) != 0) {
- if (gEventRecord.what == keyDown) {
- menuChoice = MenuKey(gEventRecord.message & charCodeMask);
- if (HiWord(menuChoice) != 0)
- DoCommand(menuChoice);
- }
- }
- break;
- case mouseDown:
- DoMouseEvent();
- break;
- case updateEvt:
- theWindow = (WindowPtr) gEventRecord.message;
- GetPort(&savePort);
- SetPort(theWindow);
- BeginUpdate(theWindow);
- EraseRect(&theWindow->portRect);
- DrawControls(theWindow);
- DrawGrowIcon(theWindow);
- EndUpdate(theWindow);
- SetPort(savePort);
- break;
- case activateEvt:
- theWindow = (WindowPtr) gEventRecord.message;
- isActivating = ((gEventRecord.modifiers & activeFlag) != 0);
- goto activateEvent;
- break;
- case osEvt:
- switch (((unsigned long) gEventRecord.message) >> 24) {
- case mouseMovedMessage:
- break;
- case suspendResumeMessage:
- isActivating = ((gEventRecord.message & 0x01) != 0);
- activateEvent: if (isActivating) {
- /*
- * Activate this window. Activate events define theWindow
- * from the event record, while suspend/resume uses the
- * pre-set FrontWindow value.
- */
- SelectWindow(theWindow);
- (void) TEFromScrap();
- }
- gInForeground = isActivating;
- break;
- }
- break;
- }
- }
-
-
- /*
- * DoMouseEvent
- * The user clicked on something. Handle application-wide processing here, or call
- * a Catalog Browser function for specific action.
- */
- void
- DoMouseEvent(void)
- {
- WindowPtr theWindow;
- short whichPart;
-
- whichPart = FindWindow(gEventRecord.where, &theWindow);
- switch (whichPart) {
- case inMenuBar:
- InitCursor();
- DoCommand(MenuSelect(gEventRecord.where));
- break;
- }
- }
-
- void
- DoCommand(
- long menuChoice
- )
- {
- short menuItem;
- Str255 menuText;
- GrafPtr savePort;
-
- menuItem = LoWord(menuChoice);
- switch (HiWord(menuChoice)) {
- case MENU_Apple:
- if (menuItem != kAppleAbout) {
- GetMenuItemText(gAppleMenu, menuItem, menuText);
- GetPort(&savePort);
- OpenDeskAcc(menuText);
- SetPort(savePort);
- }
- break;
- case MENU_File:
- gQuitNow = TRUE;
- switch (menuItem) {
- case kFileQuit:
- gQuitNow = TRUE;
- break;
- default:
- DebugStr("\pStrange File Menu");
- gQuitNow = TRUE;
- break;
- }
- break;
- }
- HiliteMenu(0);
- }
-
-
- OSErr
- DoBusReset(void)
- {
-
- OSErr status;
- CntrlParam pb;
-
- ShowString("\pIn DoBusReset");
- CLEAR(pb);
- pb.ioCRefNum = gDriverRefNum;
- pb.csCode = kControlDoSCSIBusReset;
- status = PBControlSync((ParmBlkPtr) &pb);
- ShowStatusString(status, "\pDoBusReset PBControl status");
- if (pb.ioResult != noErr) {
- ShowDecimal(pb.ioResult, "\pBus reset failed");
- gQuitNow = TRUE;
- }
- return (status);
- }
-
- OSErr
- DoTestUnitReady(void)
- {
- OSErr status;
- SCSI_6_Byte_Command testUnitReady;
- char foo[64];
-
- CLEAR(testUnitReady);
- testUnitReady.opcode = kScsiCmdTestUnitReady;
- ShowString("\pCalling TestUnitReady");
- status = DoNCRDriverIOWithSense(
- kNCRDriverNoDataPhase,
- gSCSITargetID,
- gSCSITargetLUN,
- (unsigned char *) &testUnitReady,
- (Ptr) foo, /* PBRead must pass a real buffer */
- 64,
- NULL
- );
- return (status);
- }
-
- OSErr
- DoDeviceInquiry(void)
- {
- OSErr status;
- SCSI_6_Byte_Command deviceInquiry;
- SCSI_Inquiry_Data inquiryData;
-
- CLEAR(deviceInquiry);
- deviceInquiry.opcode = kScsiCmdInquiry;
- deviceInquiry.len = sizeof inquiryData;
- CLEAR(inquiryData);
- ShowString("\pCalling DeviceInquiry");
- status = DoNCRDriverIOWithSense(
- kNCRDriverInputAllowed,
- gSCSITargetID,
- gSCSITargetLUN,
- (unsigned char *) &deviceInquiry,
- (Ptr) &inquiryData,
- sizeof inquiryData,
- NULL
- );
- if (status == noErr) {
- inquiryData.vendor[-1] = 8 + 16 + 4;
- ShowString(&inquiryData.vendor[-1]);
- }
- return (status);
- #undef INQUIRY
- }
-
- OSErr
- DoReadCapacity(void)
- {
- OSErr status;
- SCSI_12_Byte_Command capacityCmd;
- struct SCSI_Capacity_Data capacityData;
-
- ShowString("\pDoReadCapacity");
- CLEAR(capacityCmd);
- CLEAR(capacityData);
- /*
- * The 6-byte read command can read up to 128 blocks of data (1-127 reads that
- * number of blocks, while zero reads 128 blocks). For more flexibility, you
- * should use the 10-byte Read command.
- */
- capacityCmd.opcode = kScsiCmdReadCapacity;
- status = DoNCRDriverIOWithSense(
- kNCRDriverInputAllowed,
- gSCSITargetID,
- gSCSITargetLUN,
- (unsigned char *) &capacityCmd,
- (Ptr) &capacityData,
- sizeof capacityData,
- NULL
- );
- if (status == noErr) {
- gDeviceSize =
- ( (capacityData.lbn4 << 24)
- | (capacityData.lbn3 << 16)
- | (capacityData.lbn2 << 8)
- | (capacityData.lbn1 )
- );
- gCurrentBlockLength =
- ( (capacityData.len4 << 24)
- | (capacityData.len3 << 16)
- | (capacityData.len2 << 8)
- | (capacityData.len1 )
- );
- WriteLogEntry(gLogRecordPtr, 'Test',
- LogFormat3(kLogFormatUnsigned, kLogFormatUnsigned, kLogFormatString),
- gDeviceSize, gCurrentBlockLength,
- "\pDevice Size, Block Length"
- );
- }
- return (status);
- }
-
- OSErr
- DoReadBlock(
- unsigned long blockNumber,
- unsigned long nBlocks,
- Boolean dumpBlock
- )
- {
- OSErr status;
- SCSI_6_Byte_Command readData;
- unsigned long i;
- Boolean readSomething;
- unsigned long transferLength;
- unsigned long actualTransferLength;
-
- transferLength = nBlocks * gCurrentBlockLength;
- ClearMemory(gReadBufferPtr, transferLength);
- CLEAR(readData);
- /*
- * The 6-byte read command can read up to 128 blocks of
- * data (1-127 reads that number of blocks, while zero
- * reads 128 blocks). For more flexibility, you should
- * use the 10-byte Read command.
- */
- readData.opcode = kScsiCmdRead6;
- readData.len = nBlocks;
- if (readData.len == 0) /* Zero means 128 */
- readData.len = 1;
- readData.lbn3 = (blockNumber >> 16) & 0xFF;
- readData.lbn2 = (blockNumber >> 8) & 0xFF;
- readData.lbn1 = (blockNumber >> 0) & 0xFF;
- WriteLogEntry(gLogRecordPtr, 'Read',
- LogFormat4(kLogFormatUnsigned, kLogFormatUnsigned,
- kLogFormatUnsigned, kLogFormatString),
- blockNumber, nBlocks, transferLength,
- "\pRead block"
- );
- status = DoNCRDriverIOWithSense(
- kNCRDriverInputAllowed,
- gSCSITargetID,
- gSCSITargetLUN,
- (unsigned char *) &readData,
- (Ptr) gReadBufferPtr,
- transferLength,
- &actualTransferLength
- );
- readSomething = FALSE;
- for (i = 0; i < actualTransferLength; i++) {
- if (gReadBufferPtr[i] != 0) {
- readSomething = TRUE;
- break;
- }
- }
- if (dumpBlock) {
- if (readSomething == FALSE)
- ShowDecimal(blockNumber, "\pReadBlock is NULL after read");
- else {
- ShowDecimal(blockNumber, "\pReadBlock results");
- ShowMemory((Ptr) gReadBufferPtr, actualTransferLength);
- }
- }
- if (status == noErr && actualTransferLength != transferLength) {
- ShowString("\pShort transfer");
- status = ioErr;
- }
- return (status);
- }
-
- OSErr
- DoNCRDriverIOWithSense(
- unsigned short driverAction, /* Input, output, or nothing */
- unsigned short targetID, /* SCSI Bus ID */
- unsigned short targetLUN, /* SCSI LUN -- not supported */
- const unsigned char *scsiCommand, /* SCSI Command itself */
- Ptr dataBufferPtr, /* User data buffer or NULL */
- unsigned long transferCount,
- unsigned long *actualTransferCount
- )
- {
- OSErr status;
- Boolean retry;
- short trials;
-
- retry = TRUE;
- for (trials = 0; trials < 3 && retry; trials++) {
- retry = FALSE;
- status = DoNCRDriverIO(
- driverAction,
- targetID,
- targetLUN,
- scsiCommand,
- dataBufferPtr,
- transferCount,
- actualTransferCount
- );
- if (status == scsiNonZeroStatus) {
- retry = DoRequestSense(targetID, targetLUN);
- if (retry)
- ShowString("\pRetry after Unit Attention");
- }
- };
- return (status);
- }
-
- /*
- * Return TRUE if this is Unit Attention
- */
- Boolean
- DoRequestSense(
- unsigned short targetID, /* SCSI Bus ID */
- unsigned short targetLUN /* SCSI LUN -- not supported */
- )
- {
- OSErr status;
- SCSI_6_Byte_Command requestSense;
- unsigned long actualTransferCount;
- SCSI_Sense_Data sense;
- Boolean result;
-
- CLEAR(requestSense);
- CLEAR(sense);
- requestSense.opcode = kScsiCmdRequestSense;
- requestSense.len = sizeof sense;
- status = DoNCRDriverIO(
- kNCRDriverInputAllowed,
- targetID,
- targetLUN,
- (unsigned char *) &requestSense,
- (Ptr) &sense,
- sizeof sense,
- &actualTransferCount
- );
- result = ShowRequestSense(targetID, targetLUN, status, &sense, actualTransferCount);
- return (result);
- }
-
- /*
- * DoNCRDriverIO returns kNCRNonZeroStatus if the target returned CheckCondition.
- */
- OSErr
- DoNCRDriverIO(
- unsigned short driverAction, /* Input, output, or nothing */
- unsigned short targetID, /* SCSI Bus ID */
- unsigned short targetLUN, /* SCSI LUN -- not supported */
- const unsigned char *scsiCommand, /* SCSI Command itself */
- Ptr dataBufferPtr, /* User data buffer or NULL */
- unsigned long transferCount,
- unsigned long *actualTransferCount
- )
- {
- OSErr status;
- #define NCR (gNCRSCSIParam)
- #define PB (gIOParam)
-
- status = noErr;
- /*
- * Setup the parameter block
- */
- CLEAR(PB);
- CLEAR(NCR);
- PB.ioRefNum = gDriverRefNum;
- NCR.driverAction = driverAction;
- NCR.targetID = targetID;
- NCR.logicalUnitNumber = targetLUN;
- NCR.scsiCommandLength = SCSIGetCommandLength(scsiCommand);
- BlockMove(scsiCommand, NCR.scsiCommand, NCR.scsiCommandLength);
- NCR.watchdogTimeout = kTimeout; /* Presumably a two second timeout */
- PB.ioMisc = (Ptr) &gNCRSCSIParam;
- PB.ioBuffer = dataBufferPtr;
- PB.ioReqCount = transferCount;
- if ((driverAction & kNCRDriverOutputAllowed) != 0)
- status = PBWriteSync((ParmBlkPtr) &PB);
- else {
- status = PBReadSync((ParmBlkPtr) &PB);
- }
- if (actualTransferCount != NULL)
- *actualTransferCount = PB.ioActCount;
- if (PB.ioResult == ioErr)
- gQuitNow = TRUE;
- WriteLogEntry(
- gLogRecordPtr, 'DoIO',
- LogFormat5(
- kLogFormatSigned, kLogFormatSigned, kLogFormatUnsigned,
- kLogFormatUnsigned, kLogFormatString
- ),
- (signed long) status,
- (signed long) PB.ioResult,
- transferCount,
- PB.ioActCount,
- "\pDoDriveriO"
- );
- if (PB.ioResult == scsiCommandTimeout) {
- status = DoIORundown();
- gQuitNow = TRUE;
- }
- return (status);
- #undef PB
- #undef NCR
- }
-
- /*
- * The timer fired and we may be stuck with the bus busy. Try to rundown I/O using
- * our private Control call. For the time being, we don't attempt another timeout.
- */
- OSErr
- DoIORundown(void)
- {
- OSErr status;
-
- NCRDriverRundownParam pb;
-
- CLEAR(pb);
- pb.ioCRefNum = gDriverRefNum;
- pb.csCode = kControlDoSCSIRundown;
- pb.watchdogTimeout = kNoSCSITimeout;
- ShowString("\pCalling DoIORundown");
- status = PBControlSync((ParmBlkPtr) &pb);
- ShowStatusString(status, "\pDoIORundown PBControl status");
- gQuitNow = TRUE;
- return (status);
- }
-
- unsigned long
- SCSIGetCommandLength(
- const unsigned char *cmdBlock
- )
- {
- unsigned long result;
- /*
- * Look at the "group code" in the command operation. Return a parameter
- * error for the reserved (3, 4) and vendor-specific command (6, 7)
- * command groups. Otherwise, set the command length from the group code
- * value as specified in the SCSI-II spec. Then, copy the command block
- * into the parameter block (this centralizes everything for debugging
- * convenience).
- */
- switch (cmdBlock[0] & 0xE0) {
- case (0 << 5): result = 6; break;
- case (1 << 5):
- case (2 << 5): result = 10; break;
- case (5 << 5): result = 12; break;
- default: result = 0; break; /* This results in an error */
- }
- return (result);
- }
-
-
- Boolean
- ShowRequestSense(
- unsigned short targetID, /* SCSI Bus ID */
- unsigned short targetLUN, /* SCSI LUN -- not supported */
- OSErr callStatus, /* DoDriverIO Request Sense */
- const SCSI_Sense_Data *sense,
- unsigned long actualTransferCount
- )
- {
- Boolean result;
- Str255 work;
- static const StringPtr gSenseKeyText[] = {
- "\p No error",
- "\p Recovered error",
- "\p Not ready",
- "\p Medium error",
- "\p Hardware error",
- "\p Illegal request",
- "\p Unit attention",
- "\p Data protection",
- "\p Blank check",
- "\p Vendor specific",
- "\p Copy aborted",
- "\p Command aborted",
- "\p Compare equal",
- "\p Volume overflow",
- "\p Miscompare",
- "\p Reserved"
- };
- #define SENSE (*sense)
-
- result = FALSE;
- WriteLogEntry(gLogRecordPtr, 'Sens',
- LogFormat5(kLogFormatUnsigned, kLogFormatUnsigned,
- kLogFormatSigned, kLogFormatUnsigned, kLogFormatString),
- (UInt32) targetID, (UInt32) targetLUN, (SInt32) callStatus,
- (UInt32) actualTransferCount,
- "\pbus lun stat trans"
- );
- if (actualTransferCount != sizeof SENSE) {
- WriteLogEntry(gLogRecordPtr, 'Sens',
- LogFormat3(kLogFormatUnsigned, kLogFormatUnsigned, kLogFormatString),
- (UInt32) actualTransferCount, (UInt32) sizeof SENSE,
- "\pRead, sizeof sense"
- );
- }
- ShowMemory((Ptr) &SENSE, actualTransferCount);
- PStrCopy(work, "\pSense: ");
- AppendHexLeadingZeros(work, SENSE.errorCode, 2);
- if ((SENSE.errorCode & kScsiSenseInfoMask) != kScsiSenseInfoValid)
- PStrCat(work, "\p Invalid Sense");
- else {
- PStrCat(work, gSenseKeyText[SENSE.senseKey & kScsiSenseKeyMask]);
- if ((SENSE.senseKey & kScsiSenseILI) != 0)
- PStrCat(work, "\p ILI");
- if ((SENSE.senseKey & kScsiSenseEOM) != 0)
- PStrCat(work, "\p EOM");
- if ((SENSE.senseKey & kScsiSenseFileMark) != 0)
- PStrCat(work, "\p EOF");
- WriteLogEntry(gLogRecordPtr, 'Sens', kLogFormatString, work);
- work[0] = 0;
- AppendHexLeadingZeros(work, SENSE.additionalSenseCode & 0xFF, 2);
- PStrCat(work, "\p ");
- AppendHexLeadingZeros(work, SENSE.additionalSenseQualifier & 0xFF, 2);
- PStrCat(work, "\p ASC ASQ");
- result = ((SENSE.senseKey & kScsiSenseKeyMask) == kScsiSenseUnitAtn);
- }
- WriteLogEntry(gLogRecordPtr, 'Sens', kLogFormatString, work);
- return (result);
- #undef SENSE
- }
-
-
- void
- ShowMemory(
- const Ptr memStart,
- unsigned long byteCount
- )
- {
- unsigned long startIndex;
- unsigned long endIndex;
- unsigned long i;
- Str255 work;
-
- /*
- * WriteLogEntry writes up to 40 characters. This is organized as
- * Start Index 3
- * 4 groups of 4 bytes: 4 * (8 + 1)
- * One left over for good luck.
- */
- if (byteCount > 32) byteCount = 32;
- ShowDecimal(byteCount, "\pMemory Dump");
- for (startIndex = 0; startIndex < byteCount; startIndex += 16) {
- endIndex = startIndex + 16;
- if (endIndex > byteCount)
- endIndex = byteCount;
- work[0] = 0;
- AppendHexLeadingZeros(work, startIndex, 3);
- for (i = startIndex; i < endIndex; i++) {
- if ((i & 0x03) == 0x00)
- AppendChar(work, ' ');
- AppendHexLeadingZeros(work, memStart[i], 2);
- }
- ShowString(work);
- }
- }
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Output a string of hex digits with leading zeros. May not move memory. Note that
- * "digits" is the field width, not the number of hex bytes. Debug only.
- */
- void
- AppendHexLeadingZeros(
- StringPtr result,
- unsigned long value,
- short fieldWidth
- )
- {
- if (--fieldWidth > 0)
- AppendHexLeadingZeros(result, value >> 4, fieldWidth);
- value &= 0x0F;
- AppendChar(result,
- (value < 10)
- ? value + '0'
- : (value + ('A' - 10))
- );
- }
-
- void
- AppendSigned(
- StringPtr result,
- signed long value
- )
- {
- if (value < 0) {
- AppendChar(result, '-');
- value = (-value);
- }
- AppendUnsigned(result, (unsigned long) value);
- }
-
- void
- AppendUnsigned(
- StringPtr result,
- unsigned long value
- )
- {
- if (value >= 10)
- AppendUnsigned(result, value / 10);
- AppendChar(result, (value % 10) + '0');
- }
-
- void
- ClearMemory(
- register Ptr memPtr,
- register Size memSize
- )
- {
- while (memSize > 0) {
- *memPtr++ = 0;
- --memSize;
- }
- }
-